﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Collections.ObjectModel;
using System.ServiceModel.Activation;
using System.Threading;

namespace Airport
{
    
    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class AirportService : IAirportService
    {

        public static Dictionary<IAirportCallback, IAirportCallback> _clients =
            new Dictionary<IAirportCallback, IAirportCallback>();

        public AirportService()
        {
            new Thread(new ThreadStart(pumpUpdates))
            {
                IsBackground = true
            }
            .Start();

        }

        public void RegisterForFlightUpdates()
        {
            IAirportCallback c = OperationContext.Current.GetCallbackChannel<IAirportCallback>();
            if (!_clients.ContainsKey(c))
            {
                lock (_clients)
                {
                    _clients.Add(c, c);
                }
            }
        }

        public void UnregisterForFlightUpdates()
        {
            IAirportCallback c = OperationContext.Current.GetCallbackChannel<IAirportCallback>();
            if (_clients.ContainsKey(c))
            {
                lock (_clients)
                {
                    _clients.Remove(c);
                }
            }
        }

        public void pumpUpdates()
        {
            Random w = new Random();

            List<IAirportCallback> bad = new List<IAirportCallback>();
            int count = 0;

            while (true)
            {
                Thread.Sleep(w.Next(10000));

                lock (_clients)
                {
                    if (_clients.Count > 0)
                    {
                        bad.Clear();
                        foreach (IAirportCallback client in _clients.Keys)
                        {
                            try
                            {
                                //client.newFlightUpdate("Flight");
                                // This is for testing
                                Flight testFlight = new Flight();
                                testFlight.airlineCode = ((count % 2) == 0) ? "SWA" : "VA";
                                testFlight.flightNumber = count;
                                client.newFlightUpdate(testFlight);
                                //count++;
                            }
                            catch (Exception)
                            {
                                Console.WriteLine("AirportService: Calling client.newFlightUpdate failed");
                                bad.Add(client);
                            }
                        }
                        count++;
                        bad.ForEach(bc => _clients.Remove(bc));
                    }
                }
            }
        }
        
    }
    
}
